﻿// 标准库或者第三方库
#include <unordered_map>
#include <unordered_set>
#include <iostream>
#include <numeric>
#include <cmath>

// 自定义头文件
#include "template_problem04.hxx"

// ACIS
#include "acis/acis.hxx"
#include "acis/api.err"
#include "acis/api.hxx"
#include "acis/api_sample_faces.hxx"
#include "acis/body.hxx"
#include "acis/box.hxx"
#include "acis/bool_api_options.hxx"
#include "acis/curve.hxx"
#include "acis/check.hxx"
#include "acis/cstrapi.hxx"
#include "acis/ckoutcom.hxx"
#include "acis/cone.hxx"
#include "acis/entity.hxx"
#include "acis/euler.hxx"
#include "acis/faceutil.hxx"
#include "acis/getbox.hxx"
#include "acis/intrapi.hxx"
#include "acis/kernapi.hxx"
#include "acis/logical.h"
#include "acis/module.hxx"
#include "acis/primtive.hxx"
#include "acis/plane.hxx"
#include "acis/sphere.hxx"
#include "acis/torus.hxx"
#include "acis/ptfcenum.hxx"
#include "acis/raytest.hxx"
#include "acis/rayfire_opts.hxx"
#include "same_entity.hpp"
#include "acis/surface.hxx"
#include "acis/stch_utl_stitch.hxx"
#include "acis/stch_utl.hxx"
#include "acis/spline.hxx"
#include "acis/vector_utils.hxx"

// ************************************************************
outcome answer_api_make_cuboid(double width, double depth, double height, BODY*& body) {
	API_BEGIN
		if (api_checking_on) {
			check_pos_length(width, "width");
			check_pos_length(depth, "depth");
			check_non_neg_length(height, "height");
		}
	body = make_parallelepiped(width, depth, height);
	printf("hello");
	API_END
		return result;
}
// ************************************************************

// 根据射线命中结果，分析采样点相对于目标实体的关系
enum FacePosition { INTERNAL, EXTERNAL, INTERSECTING, COINCIDING, BOUNDARY, UNKNOWN };

class face_point_info {
public:
	SPAposition point;  // 点的三维位置
	bool used;          // 是否被使用
	SURFACE* geometry;  // 面的几何
	tag_id_type tag_id; // 面的标识

	// 默认构造函数
	face_point_info()
		: point(), used(false), geometry(nullptr), tag_id(0) {}

	// 参数化构造函数
	face_point_info(SPAposition p, bool u, SURFACE* g, tag_id_type t)
		: point(p), used(u), geometry(g), tag_id(t) {}
};

// 计算并返回BODY的AABB包围盒
SPAbox* build_BODY_bound(BODY* body) {
	// 获取 BODY 的原始包围盒
	SPAbox* ori_body_box = body->bound();
	if (ori_body_box != nullptr) {
		// 如果原始包围盒存在，创建一个新的SPAbox对象作为副本并返回
		SPAbox* body_box = new SPAbox(*ori_body_box);
		return body_box;
	}

	// 如果BODY没有包围盒，从BODY中获取第一个块（LUMP）
	LUMP* current_lump = body->lump();
	SPAbox combined_lump_box; // 用于存储合并后的块包围盒
	bool has_lump_box = false; // 标记是否已经计算过块的包围盒

	// 遍历BODY中的所有块（LUMP）
	while (current_lump != nullptr) {
		// 获取当前块的原始包围盒
		SPAbox* ori_lump_box = current_lump->bound();
		if (ori_lump_box != nullptr) {
			// 如果块有包围盒，创建一个新的SPAbox对象作为副本
			SPAbox lump_box = *ori_lump_box;
			if (has_lump_box) {
				// 如果已经计算过块的包围盒，合并当前块的包围盒
				combined_lump_box = combined_lump_box | lump_box;
			}
			else {
				// 如果这是第一个块的包围盒，直接赋值
				combined_lump_box = lump_box;
				has_lump_box = true;
			}
		}
		else {
			// 如果块没有包围盒，遍历块中的所有壳（SHELL）
			SHELL* current_shell = current_lump->shell();
			SPAbox combined_shell_box; // 用于存储合并后的壳包围盒
			bool has_shell_box = false; // 标记是否已经计算过壳的包围盒

			// 遍历块中的所有壳
			while (current_shell != nullptr) {
				// 获取当前壳的原始包围盒
				SPAbox* ori_shell_box = current_shell->bound();
				if (ori_shell_box != nullptr) {
					// 如果壳有包围盒，创建一个新的SPAbox对象作为副本
					SPAbox shell_box = *ori_shell_box;
					if (has_shell_box) {
						// 如果已经计算过壳的包围盒，合并当前壳的包围盒
						combined_shell_box = combined_shell_box | shell_box;
					}
					else {
						// 如果这是第一个壳的包围盒，直接赋值
						combined_shell_box = shell_box;
						has_shell_box = true;
					}
				}
				else {
					// 如果壳没有包围盒，遍历壳中的所有子壳（SUBSHELL）
					SUBSHELL* current_subshell = current_shell->subshell();
					SPAbox combined_subshell_box; // 用于存储合并后的子壳包围盒
					bool has_subshell_box = false; // 标记是否已经计算过子壳的包围盒

					// 遍历壳中的所有子壳
					while (current_subshell != nullptr) {
						// 获取当前子壳的原始包围盒
						SPAbox* ori_subshell_box = current_subshell->bound();
						if (ori_subshell_box != nullptr) {
							// 如果子壳有包围盒，创建一个新的SPAbox对象作为副本
							SPAbox subshell_box = *ori_subshell_box;
							if (has_subshell_box) {
								// 如果已经计算过子壳的包围盒，合并当前子壳的包围盒
								combined_subshell_box = combined_subshell_box | subshell_box;
							}
							else {
								// 如果这是第一个子壳的包围盒，直接赋值
								combined_subshell_box = subshell_box;
								has_subshell_box = true;
							}
						}
						else {
							// 如果子壳没有包围盒，遍历子壳中的所有面（FACE）
							FACE* current_face = current_subshell->face();
							SPAbox combined_face_box; // 用于存储合并后的面包围盒
							bool has_face_box = false; // 标记是否已经计算过面的包围盒

							// 遍历子壳中的所有面
							while (current_face != nullptr) {
								// 获取当前面的包围盒
								SPAbox face_box = get_face_box(current_face);
								if (has_face_box) {
									// 如果已经计算过面的包围盒，合并当前面的包围盒
									combined_face_box = combined_face_box | face_box;
								}
								else {
									// 如果这是第一个面的包围盒，直接赋值
									combined_face_box = face_box;
									has_face_box = true;
								}
								// 移动到下一个面
								current_face = current_face->next();
							}

							// 如果有面的包围盒，合并到子壳的包围盒中
							if (has_face_box) {
								if (has_subshell_box) {
									combined_subshell_box = combined_subshell_box | combined_face_box;
								}
								else {
									combined_subshell_box = combined_face_box;
									has_subshell_box = true;
								}
							}
						}
						// 移动到下一个子壳
						current_subshell = current_subshell->sibling();
					}

					// 如果有子壳的包围盒，合并到壳的包围盒中
					if (has_subshell_box) {
						if (has_shell_box) {
							combined_shell_box = combined_shell_box | combined_subshell_box;
						}
						else {
							combined_shell_box = combined_subshell_box;
							has_shell_box = true;
						}
					}
				}
				// 移动到下一个壳
				current_shell = current_shell->next(PAT_CAN_CREATE);
			}

			// 如果有壳的包围盒，合并到块的包围盒中
			if (has_shell_box) {
				if (has_lump_box) {
					combined_lump_box = combined_lump_box | combined_shell_box;
				}
				else {
					combined_lump_box = combined_shell_box;
					has_lump_box = true;
				}
			}
		}
		// 移动到下一个块
		current_lump = current_lump->next(PAT_CAN_CREATE);
	}

	// 如果有块的包围盒，创建一个新的SPAbox对象并返回
	if (has_lump_box) {
		return new SPAbox(combined_lump_box);
	}
	else {
		// 如果没有找到任何包围盒，返回nullptr
		return nullptr;
	}
}


// 通过 ENTITY 类型获取所有 FACE 指针
std::vector<FACE*> getFacesFromEntity(ENTITY* entity) {
	std::vector<FACE*> faces;
	// 获取 ENTITY 的类型名称
	std::string typeName = entity->type_name();
	if (typeName == "body") {
		// ENTITY 是 BODY
		BODY* body = static_cast<BODY*>(entity);
		LUMP* lump = body->lump();
		while (lump) {
			SHELL* shell = lump->shell();
			while (shell) {
				if (SUBSHELL* subshell = shell->subshell()) {
					// SHELL 下有 SUBSHELL 链表
					while (subshell) {
						FACE* face = subshell->face();
						while (face) {
							faces.push_back(face);
							face = face->next();  // 获取 SUBSHELL 下一个 FACE
						}
						subshell = subshell->sibling();  // 获取下一个 SUBSHELL
					}
				}
				else {
					// SHELL 直接有 FACE 链表
					FACE* face = shell->face();
					while (face) {
						faces.push_back(face);
						face = face->next();  // 获取 SHELL 下一个 FACE
					}
				}
				shell = shell->next();  // 获取下一个 SHELL
			}
			lump = lump->next();  // 获取下一个 LUMP
		}
	}
	else if (typeName == "lump") {
		// ENTITY 是 LUMP
		LUMP* lump = static_cast<LUMP*>(entity);
		SHELL* shell = lump->shell();
		while (shell) {
			if (SUBSHELL* subshell = shell->subshell()) {
				// SHELL 下有 SUBSHELL 链表
				while (subshell) {
					FACE* face = subshell->face();
					while (face) {
						faces.push_back(face);
						face = face->next();  // 获取 SUBSHELL 下一个 FACE
					}
					subshell = subshell->sibling();  // 获取下一个 SUBSHELL
				}
			}
			else {
				// SHELL 直接有 FACE 链表
				FACE* face = shell->face();
				while (face) {
					faces.push_back(face);
					face = face->next();  // 获取 SHELL 下一个 FACE
				}
			}
			shell = shell->next();  // 获取下一个 SHELL
		}
	}
	else if (typeName == "shell") {
		// ENTITY 是 SHELL
		SHELL* shell = static_cast<SHELL*>(entity);
		if (SUBSHELL* subshell = shell->subshell()) {
			// SHELL 下有 SUBSHELL 链表
			while (subshell) {
				FACE* face = subshell->face();
				while (face) {
					faces.push_back(face);
					face = face->next();  // 获取 SUBSHELL 下一个 FACE
				}
				subshell = subshell->sibling();  // 获取下一个 SUBSHELL
			}
		}
		else {
			// SHELL 直接有 FACE 链表
			FACE* face = shell->face();
			while (face) {
				faces.push_back(face);
				face = face->next();  // 获取 SHELL 下一个 FACE
			}
		}
	}
	else if (typeName == "subshell") {
		// ENTITY 是 SUBSHELL
		SUBSHELL* subshell = static_cast<SUBSHELL*>(entity);
		FACE* face = subshell->face();
		while (face) {
			faces.push_back(face);
			face = face->next();  // 获取 SUBSHELL 下一个 FACE
		}
	}
	else if (typeName == "face") {
		// ENTITY 是 FACE
		FACE* face = static_cast<FACE*>(entity);
		faces.push_back(face);
	}
	else {
		// ENTITY 类型不匹配，抛出异常
		throw std::invalid_argument("Unsupported ENTITY type");
	}
	return faces;
}

//分析两个BODY之间的包围盒干涉关系
void processBodyInterference(BODY* tool, BODY* blank, std::unordered_map<FACE*, std::vector<FACE*>>& face_face_map, std::unordered_map<FACE*, std::vector<LUMP*>>& face_lump_map) {
	// 获取tool和blank的BODY包围盒
	SPAbox* blank_bound = blank->bound();

	// 获取tool和blank中的FACE集合
	std::vector<FACE*> blank_faces = getFacesFromEntity(blank);

	// 检查每个tool的LUMP与blank的BODY包围盒是否相交
	for (LUMP* tool_lump = tool->lump(); tool_lump != nullptr; tool_lump = tool_lump->next()) {
		SPAbox* tool_lump_bound = tool_lump->bound();

		if (!(*tool_lump_bound && *blank_bound)) {
			// 如果tool的LUMP与blank的BODY包围盒不相交
			for (FACE* blank_face : blank_faces) {
				face_lump_map[blank_face].push_back(tool_lump);  // 将该LUMP添加到blank的每个FACE的face_lump_map中
			}
			continue;  // 跳过不相交的LUMP，继续下一个LUMP
		}

		// 对于与blank的BODY包围盒相交的tool的LUMP，进一步检查与blank的每个LUMP的包围盒相交情况
		for (LUMP* blank_lump = blank->lump(); blank_lump != nullptr; blank_lump = blank_lump->next()) {
			SPAbox* blank_lump_bound = blank_lump->bound();
			std::vector<FACE*> tool_lump_faces = getFacesFromEntity(tool_lump);
			if (!(*tool_lump_bound && *blank_lump_bound)) {
				// 如果tool的当前LUMP与blank的某个LUMP不相交
				for (FACE* tool_face : tool_lump_faces) {
					face_lump_map[tool_face].push_back(blank_lump);  // 将blank的该LUMP添加到tool的每个相交FACE的face_lump_map中
				}
			}
			else {
				// 如果tool的LUMP与blank的LUMP相交，将tool和blank的FACE映射到face_face_map
				std::vector<FACE*> blank_lump_faces = getFacesFromEntity(blank_lump);
				for (FACE* face1 : tool_lump_faces) {
					for (FACE* face2 : blank_lump_faces) {
						face_face_map[face1].push_back(face2);
						face_face_map[face2].push_back(face1);
					}
				}
			}
		}
	}
}

// 在指定的FACE上找到一个内部点
logical get_point_in_face(FACE* face, SPAposition& point, SPAtransf& transf, int max_sample_num = 1000) {
	API_BEGIN

		// 将FACE的几何体转换为surface对象，应用变换transf
		surface* surf = face->geometry()->trans_surface(transf);

	// 定义一个lambda函数用于采样点
	auto sample_point = [&](SPAinterval u_range, SPAinterval v_range) {
		// 初始化采样点数量，初始值为10
		int sample_num = 10;
		std::vector<SPAposition> points;                // 存储一轮中采样到的点
		std::vector<SPAposition> face_boundary_points;  // 存储face边界上采样的点
		logical found_point = FALSE;  // 标记是否找到内部点

		// 获取face的边和顶点
		ENTITY_LIST target_face_edges = ENTITY_LIST();
		check_outcome(api_get_edges(face, target_face_edges));
		ENTITY_LIST target_face_vertices = ENTITY_LIST();
		check_outcome(api_get_vertices(face, target_face_vertices));

		// 找到参数差距最小的边，作为采样的参考
		double min_param_dist = DBL_MAX;
		for (int i = 0, n = target_face_edges.iteration_count(); i < n; i++) {
			EDGE* edge = (EDGE*)target_face_edges[i];
			if (edge->start() == edge->end()) {
				continue;
			}
			double param_dist = edge->end_param() - edge->start_param();
			if (param_dist < min_param_dist) {
				min_param_dist = param_dist;
			}
		}

		// 采样边界上的点
		int sample_offset = 1;
		for (int i = 0, n = target_face_edges.iteration_count(); i < n; i++) {
			EDGE* edge = (EDGE*)target_face_edges[i];
			if (edge->start() == edge->end()) {
				continue;
			}

			int edge_sample_num = (int)((edge->end_param() - edge->start_param()) / min_param_dist) + sample_offset;
			double step = (edge->end_param() - edge->start_param()) / edge_sample_num;
			curve* c = edge->geometry()->trans_curve(transf);

			// 不采样端点，否则会重复
			for (int j = 1; j < edge_sample_num; j++) {
				double param = edge->start_param() + step * j;
				SPAposition p;
				c->eval(param, p);
				face_boundary_points.push_back(p);
			}
			ACIS_DELETE c;
			c = nullptr;
		}

		// 加入edge的端点
		for (int i = 0, n = target_face_vertices.iteration_count(); i < n; i++) {
			VERTEX* vertex = (VERTEX*)target_face_vertices[i];
			SPAposition p = vertex->geometry()->coords();
			face_boundary_points.push_back(p);
		}

		// 进行采样，直到找到内部点或超过最大采样次数
		while (sample_num <= max_sample_num) {
			double u_step = (u_range.end_pt() - u_range.start_pt()) / sample_num;
			double v_step = (v_range.end_pt() - v_range.start_pt()) / sample_num;
			points.clear();

			// 减去首尾，避免采样到边界点
			for (int i = 0; i < sample_num; i++) {
				for (int j = 0; j < sample_num; j++) {
					double u = u_range.start_pt() + i * u_step;
					double v = v_range.start_pt() + j * v_step;

					// 尝试采样
					SPAposition sample_point;
					surf->eval(SPApar_pos(u, v), sample_point);
					point_face_containment pfc;
					check_outcome(api_point_in_face(sample_point, face, transf, pfc, SPApar_pos(u, v)));

					if (pfc == point_inside_face) {
						points.push_back(sample_point);
						found_point = TRUE;
					}
				}
			}

			// 如果找到了至少一个位于face内部的采样点，接下来需要确定哪个点最有可能是face的中心点
			if (found_point) {
				// 如果face有边，那么我们可以通过计算采样点到face顶点的距离方差来找到中心点
				if (target_face_edges.iteration_count() > 0) {
					double min_variance = DBL_MAX; // 用于记录最小方差的值
					SPAposition best_point; // 用于记录方差最小的点，即最可能的中心点

					// 遍历所有采样到的内部点
					for (int i = 0, n = points.size(); i < n; i++) {
						double variance = 0; // 存储当前点的距离方差
						double average_distance = 0.0; // 存储当前点到所有顶点的平均距离
						std::vector<double> distances; // 存储当前点到所有顶点的距离

						// 计算当前采样点到face所有顶点的距离
						for (int j = 0, m = face_boundary_points.size(); j < m; j++) {
							distances.push_back(distance_to_point(points[i], face_boundary_points[j]));
						}

						// 计算当前点到所有顶点的平均距离
						average_distance = std::accumulate(distances.begin(), distances.end(), 0.0) / distances.size();

						// 计算当前点的距离方差
						for (double distance : distances) {
							variance += pow(distance - average_distance, 2);
						}
						variance /= distances.size();

						// 如果当前点的方差小于已知的最小方差，则更新最小方差和最佳点
						if (variance < min_variance) {
							min_variance = variance;
							best_point = points[i];
						}
					}

					// 将计算出的中心点赋值给输出参数point，并返回成功
					point = best_point;
					return TRUE;
				}
				// 如果face没有边，那么简单地选择采样到的点列表中的中间点作为中心点
				else {
					point = points[points.size() / 2];
					return TRUE;
				}
			}
			sample_num *= 2;
			std::cout << "sample_num:" << sample_num << std::endl;
		}
		return FALSE;
	};

	// 获取face的参数化包围盒
	SPApar_box uv_box;
	sg_get_face_par_box(face, uv_box);
	SPAinterval u_range = uv_box.u_range();
	SPAinterval v_range = uv_box.v_range();

	// 首先在face的参数化包围盒内采样
	if (sample_point(u_range, v_range)) {
		ACIS_DELETE surf;
		surf = nullptr;
		return TRUE;
	}
	else {
		// 如果未找到，尝试在face的实体包围盒内采样
		SPAposition min_pt, max_pt;
		check_outcome(api_get_entity_box(face, min_pt, max_pt));
		SPAbox box(min_pt, max_pt);

		u_range = surf->param_range_u(box);
		v_range = surf->param_range_v(box);
		logical res = sample_point(u_range, v_range);
		ACIS_DELETE surf;
		surf = nullptr;
		return res;
	}

	ACIS_DELETE surf;
	API_END
		return FALSE;
}
// 判断一个点与一个BODY的空间位置关系
bool atom_api_point_in_body(const SPAposition& test_point, BODY* target_body, point_containment& pc, bool use_boxes) {
	API_BEGIN
		// 使用包围盒进行粗略判断
		if (use_boxes) {
			SPAposition max_point, min_point;
			api_get_entity_box(target_body, min_point, max_point);

			// 点在包围盒外，直接返回结果，否则继续用射线法判断
			SPAbox box(min_point, max_point);
			if (!(test_point << box)) {
				pc = point_outside;
				return true;
			}
		}

	// 使用多次射线法精确判断
	std::vector<SPAunit_vector> dirs = {
		SPAunit_vector(0, 0, 1),
		SPAunit_vector(-0.0005, 0.0005, 0.999),
		SPAunit_vector(-0.0005, -0.0005, 0.999),
		SPAunit_vector(0.0007, 0.0003, 0.999),
		SPAunit_vector(-0.0007, 0.0003, 0.999),
		SPAunit_vector(-0.0004, -0.0006, 0.999),
		SPAunit_vector(0.0004, -0.0006, 0.999)
	};

	std::vector<point_containment> pc_list;
	int inside_count = 0;
	int boundary_count = 0;
	int outside_count = 0;

	for (const auto& dir : dirs) {
		ray ray(test_point, dir);
		entity_hit_list hits;
		api_ray_fire(target_body, ray, hits);

		int count = hits.count();
		if (count == 0) {
			outside_count++;
			pc_list.push_back(point_outside);
			continue;
		}

		entity_hit* first_hit = hits[0];

		if (first_hit->hit_param() == 0) {
			boundary_count++;
			pc_list.push_back(point_boundary);
		}
		else if (count % 2 == 1) {
			inside_count++;
			pc_list.push_back(point_inside);
		}
		else {
			outside_count++;
			pc_list.push_back(point_outside);
		}
	}

	// 判断结果，如果有boundary判断，肯定位于边界，其余情况取多数
	if (boundary_count > 0) {
		pc = point_boundary;
	}
	else if (inside_count > outside_count) {
		pc = point_inside;
	}
	else {
		pc = point_outside;
	}

	API_END
		return true;
}


std::unordered_map<FACE*, face_point_info> face_point_map;  // 面与点信息的映射
size_t map_use_time = 0;                                    // 用于清理映射的计数器

// 判断一个 FACE 与一个 BODY 的空间位置关系
bool api_face_in_body(FACE* face, BODY* body, FacePosition& fc, bool use_boxes, int max_sample_num = 100) {
	// 提前获取包围盒信息
	SPAbox* face_box = face->bound();
	SPAbox* body_box = body->bound();
	SPAbox temp_face_box;

	if (!face_box || !body_box) {
		if (!face_box) {
			temp_face_box = get_face_box(face, nullptr, TRUE); // 获取包围盒数据
		}
		if (!body_box) {
			body_box = build_BODY_bound(body);
		}
	}

	if (use_boxes && body_box) {
		if (temp_face_box == *body_box) {
			fc = INTERSECTING;
			return true;
		}
		if (temp_face_box >> *body_box) {
			fc = EXTERNAL;
			return true;
		}
		if (temp_face_box << *body_box) {
			fc = INTERNAL;
			return true;
		}
		if (temp_face_box && *body_box) {
			fc = INTERSECTING;
			return true;
		}
	}

	// 获取body中的所有faces
	ENTITY_LIST body_faces;
	check_outcome(api_get_faces(body, body_faces));

	for (int i = 0; i < body_faces.iteration_count(); ++i) {
		FACE* body_face = static_cast<FACE*>(body_faces[i]);

		// 检查几何是否共面或共享相同曲面
		//if (face->geometry()->equation() == body_face->geometry()->equation()) {
		if (same_face(face, body_face)) {
			// 检查边界一致性
			ENTITY_LIST face_edges, body_face_edges;
			check_outcome(api_get_edges(face, face_edges));
			check_outcome(api_get_edges(body_face, body_face_edges));

			if (face_edges.iteration_count() == body_face_edges.iteration_count()) {
				bool boundaries_match = true;
				for (int j = 0; j < face_edges.iteration_count(); ++j) {
					EDGE* face_edge = static_cast<EDGE*>(face_edges[j]);
					EDGE* body_face_edge = static_cast<EDGE*>(body_face_edges[j]);

					// 检查边界是否一致
					if (face_edge->geometry() && body_face_edge->geometry()) {
						if (!(face_edge->geometry()->equation() == body_face_edge->geometry()->equation())) {
							boundaries_match = false;
							break;
						}
					}
				}
				if (boundaries_match) {
					// 检查朝向一致性
					SPAunit_vector face_normal, body_face_normal;
					REVBIT facelSense = face->sense(FALSE);
					REVBIT body_faceinternalSense = body_face->sense(FALSE);
					if (facelSense == body_faceinternalSense) {
						fc = COINCIDING;
						return true;
					}
				}
			}
		}
	}

	if (!body) {
		error_info* err_info = ACIS_NEW error_info(NULL_BODY, SPA_OUTCOME_FATAL);
		return false;
	}
	else if (!is_BODY(body)) {
		error_info* err_info = ACIS_NEW error_info(NOT_BODY, SPA_OUTCOME_FATAL);
		return false;
	}
	else if (!face) {
		error_info* err_info = ACIS_NEW error_info(NULL_FACE, SPA_OUTCOME_FATAL);
		return false;
	}
	else if (!is_FACE(face)) {
		error_info* err_info = ACIS_NEW error_info(NOT_FACE, SPA_OUTCOME_FATAL);
		return false;
	}

	// 取面上非边缘一点的uv坐标
	SPAposition test_point;
	SPAtransf transf = SPAtransf();
	if (face->shell() and face->shell()->lump() and face->shell()->lump()->body() and face->shell()->lump()->body()->transform()) {
		transf = face->shell()->lump()->body()->transform()->transform();
	}

	//SPApar_pos par_pos;
	logical found_point = FALSE;
	if (face_point_map.find(face) != face_point_map.end() and face_point_map[face].geometry == face->geometry() and face_point_map[face].tag_id == face->tag()) {
		test_point = face_point_map[face].point;
		point_face_containment pfc;
		check_outcome(api_point_in_face(test_point, face, transf, pfc));
		found_point = pfc == point_inside_face;
		face_point_map[face].used = true;
	}

	if (!found_point) {
		if (get_point_in_face(face, test_point, transf, 10000)) {
			surface* surf = face->geometry()->trans_surface(transf);
			//surf->eval(par_pos, test_point);
			ACIS_DELETE surf;
		}
		else {
			if (!get_point_in_face(face, test_point, transf)) {
				fc = UNKNOWN;
				return false;
			}
		}
		face_point_map[face] = face_point_info(test_point, true, face->geometry(), face->tag());
	}

	if (map_use_time++ % 10000 == 0) {
		for (auto it = face_point_map.begin(); it != face_point_map.end();) {
			if (!it->second.used) {
				face_point_map.erase(it++);
			}
			else {
				it->second.used = false;
				it++;
			}
		}
	}

	// 使用采样点检查面的位置关系
	int inside_count = 0, outside_count = 0, boundary_count = 0;
	//for (const auto& point : points) {
	point_containment pc;
	if (api_point_in_body(test_point, body, pc, false).ok()) {
		if (pc == point_inside) {
			inside_count++;
		}
		else if (pc == point_outside) {
			outside_count++;
		}
		else if (pc == point_boundary) {
			boundary_count++;
		}
	}

	double inside_ratio = static_cast<double>(inside_count);
	double outside_ratio = static_cast<double>(outside_count);
	double boundary_ratio = static_cast<double>(boundary_count);
	if (inside_ratio > 0.9) {
		fc = INTERNAL; // 超过90%的点在内部
	}
	else if (outside_ratio > 0.9) {
		fc = EXTERNAL; // 超过90%的点在外部
	}
	else if (boundary_ratio) {
		fc = COINCIDING;
	}
	else {
		fc = INTERSECTING; // 否则认为是相交
	}
	return true;
}


// 根据布尔运算操作选择面片 
outcome classify_faces(BODY* tool, BODY* blank, BOOL_TYPE bool_op, ENTITY_LIST& faces_to_keep, ENTITY_LIST& faces_to_discard) {
	API_BEGIN
		// 定义用于存储面分类结果的映射
		std::unordered_map<FACE*, FacePosition> face_class_map;
	std::vector<FACE*> blank_faces = getFacesFromEntity(blank);
	for (FACE* face : blank_faces) {
		if (face_class_map.find(face) != face_class_map.end()) {
			continue; // 已通过交线信息分类
		}
		FacePosition position;
		// 返回 blank 实体的每个面相比于 tool 实体的位置
		api_face_in_body(face, tool, position, false);
		face_class_map[face] = position;
	}

	std::vector<FACE*> tool_faces = getFacesFromEntity(tool);
	for (FACE* face : tool_faces) {
		if (face_class_map.find(face) != face_class_map.end()) {
			continue; // 已通过交线信息分类
		}
		FacePosition position;
		// 返回 tool 实体的每个面相比于 blank 实体的位置
		api_face_in_body(face, blank, position, false);
		face_class_map[face] = position;
	}
	// 根据布尔运算类型标记需要保留和丢弃的面
	for (auto& pair : face_class_map) {
		FACE* face = pair.first;
		FacePosition position = pair.second;
		switch (bool_op) {
		case UNION:
			if (position == EXTERNAL || position == INTERSECTING || (position == COINCIDING && face->shell()->lump()->body() == blank)) {
				faces_to_keep.add(face); // 添加到faces_to_keep
			}
			else {
				faces_to_discard.add(face); // 添加到faces_to_discard
			}
			break;
		case INTERSECTION:
			if (position == INTERNAL || position == INTERSECTING || position == BOUNDARY || (position == COINCIDING && face->shell()->lump()->body() == blank)) {
				faces_to_keep.add(face);
			}
			else {
				faces_to_discard.add(face);
			}
			break;
		case SUBTRACTION:
			if ((position == EXTERNAL || position == INTERSECTING || position == BOUNDARY) && face->shell()->lump()->body() == blank) {
				faces_to_keep.add(face);
			}
			else if ((position == INTERNAL || position == INTERSECTING || position == BOUNDARY) && face->shell()->lump()->body() == tool) {
				faces_to_keep.add(face);
			}
			else {
				faces_to_discard.add(face);
			}
			break;
		case NONREG_UNION:
		case NONREG_INTERSECTION:
		case NONREG_SUBTRACTION:
			if (position != INTERNAL) {
				faces_to_keep.add(face);
			}
			else {
				faces_to_discard.add(face);
			}
			break;
		default:
			std::cerr << "错误: 不支持的BOOL_TYPE。" << std::endl;
			return result;
		}
	}
	API_END
		return result;
}

// 重置 BODY 中所有FACE对应的surface对象
void reset_surface(BODY* body) {
	ENTITY_LIST faces = ENTITY_LIST();
	api_get_faces(body, faces);
	for (auto f : faces) {
		FACE* face = (FACE*)f;
		// 如果FACE有对应的几何体
		if (face->geometry()) {
			int identity = face->geometry()->identity();
			SURFACE* old_geometry = face->geometry();
			// 如果FACE的几何体是平面（PLANE）
			if (identity == PLANE_ID) {
				plane* pl = (plane*)face->geometry()->trans_surface();
				// 设置FACE的几何体为新的平面对象
				face->set_geometry(ACIS_NEW PLANE(*pl));
				// 删除旧的平面对象
				ACIS_DELETE pl;
			}
			else if (identity == CONE_ID) {
			}
			// 如果FACE的几何体是球体（SPHERE）
			else if (identity == SPHERE_ID) {
				sphere* sp = (sphere*)face->geometry()->trans_surface();
				face->set_geometry(ACIS_NEW SPHERE(*sp));
				ACIS_DELETE sp;
			}
			// 如果FACE的几何体是环面（TORUS）
			else if (identity == TORUS_ID) {
				torus* to = (torus*)face->geometry()->trans_surface();
				face->set_geometry(ACIS_NEW TORUS(*to));
				ACIS_DELETE to;
			}
			// 如果FACE的几何体是样条曲线（SPLINE）
			else if (identity == SPLINE_ID) {
				spline* sl = (spline*)face->geometry()->trans_surface();
				// 获取FACE的参数化包围盒
				SPApar_box par_box = SPApar_box();
				sg_get_face_par_box(face, par_box);
				// 设置样条曲线的界限为FACE的参数化包围盒
				sl->limit(par_box);
				face->set_geometry(ACIS_NEW SPLINE(*sl));
				ACIS_DELETE sl;
			}
			// 如果旧的几何体对象没有其他引用，则删除它
			if (old_geometry->use_count() == 0) {
				api_delent(old_geometry);
			}
		}
	}
}


/**
 * @brief 执行布尔操作
 * @param tool 工具体，默认在操作后被删除
 * @param blank 毛坯体，默认在操作后被修改
 * @param op 操作类型，支持 UNION, INTERSECTION, SUBTRACTION 等
 * @param ndbool_keep 非破坏性布尔操作的保留选项
 * @param result_body 输出结果体，如果执行非破坏性布尔操作
 * @param ao ACIS选项，如版本控制和日志记录
 * @return 布尔操作的结果状态
 */
outcome answer_api_boolean(BODY* tool, BODY* blank, BOOL_TYPE op, NDBOOL_KEEP ndbool_keep, BODY*& result_body, AcisOptions* ao) {

	API_BEGIN
		// 参数有效性检查
		if (tool == nullptr || blank == nullptr) {
			std::cerr << "错误: tool 或 blank 为空指针。" << std::endl;
			return outcome();
		}
	// 临时存储克隆对象
	BODY* cloned_blank = nullptr;
	BODY* cloned_tool = nullptr;

	// 根据 ndbool_keep 克隆需要保留的几何体
	if (ndbool_keep == NDBOOL_KEEP_BLANK || ndbool_keep == NDBOOL_KEEP_BOTH) {
		check_outcome(api_copy_body(blank, cloned_blank));
		if (cloned_blank == nullptr) {
			std::cerr << "错误: 无法克隆 blank。" << std::endl;
			return result;
		}
	}

	if (ndbool_keep == NDBOOL_KEEP_TOOL || ndbool_keep == NDBOOL_KEEP_BOTH) {
		check_outcome(api_copy_body(tool, cloned_tool));
		if (cloned_tool == nullptr) {
			std::cerr << "错误: 无法克隆 tool。" << std::endl;
			if (cloned_blank != nullptr) cloned_blank->lose();
			return result;
		}
	}

	// 执行imprint操作
	api_imprint(tool, blank);

	// 分类需要保留和移除的面片
	ENTITY_LIST faces_to_keep;
	ENTITY_LIST faces_to_discard;
	classify_faces(tool, blank, op, faces_to_keep, faces_to_discard);

	// 移除需要丢弃的面片
	for (int i = 0; i < faces_to_discard.count(); ++i) {
		FACE* face = static_cast<FACE*>(faces_to_discard[i]);
		kf(face, TRUE);
	}

	reset_surface(tool);
	reset_surface(blank);

	outcome res = api_stitch(blank, tool, TRUE);
	if (!res.ok()) {
		// 如果缝合失败，返回错误信息
		error_info* errinfo = res.get_error_info();
		const char* info = errinfo->error_message();
		// 检查是否是" Incompatible coedges encountered" 错误
		if (std::string(info).find("Incompatible coedges encountered") != std::string::npos) {
			api_reverse_body(tool);
		}
		// 再次调用api_stitch
		res = api_stitch(blank, tool, TRUE);
		if (res.ok()) {
		}
		else {
			std::cerr << "stitch FAILED again after edge sense reversal." << std::endl;
			error_info* errinfo_retry = res.get_error_info();
			const char* retry_info = errinfo_retry->error_message();
		}
	}

	if (ndbool_keep != NDBOOL_KEEP_NEITHER && ndbool_keep != NDBOOL_KEEP_TOOL) {
		*result_body = *blank;
	}

	if (ndbool_keep == NDBOOL_KEEP_NEITHER) {
		std::cout << "trying to clean entity" << std::endl;
		api_del_entity(tool, ao);
	}
	else if (ndbool_keep == NDBOOL_KEEP_BLANK) {
		api_del_entity(tool, ao);
		api_copy_body(cloned_blank, blank);
	}
	else if (ndbool_keep == NDBOOL_KEEP_TOOL) {
		api_copy_body(cloned_tool, tool);
	}
	else if (ndbool_keep == NDBOOL_KEEP_BOTH) {
		api_copy_body(cloned_blank, blank);
		api_copy_body(cloned_tool, tool);
	}

	API_END;
	return result;
}